package com.earthea.common.system.server;

import cn.hutool.core.date.BetweenFormatter;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.io.unit.DataSizeUtil;
import cn.hutool.system.SystemUtil;
import com.earthea.common.util.ArithUtils;
import lombok.Getter;

import java.lang.management.ManagementFactory;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.Properties;

/**
 * JVM相关信息
 */
@Getter
public class Jvm {
    /**
     * 当前JVM占用的内存总数(M)
     */
    private final long total = Runtime.getRuntime().totalMemory();

    /**
     * JVM最大可用内存总数(M)
     */
    private final long max = Runtime.getRuntime().maxMemory();

    /**
     * JVM空闲内存(M)
     */
    private final long free = Runtime.getRuntime().freeMemory();

    /**
     * JDK版本
     */
    private final String version;

    /**
     * JDK路径
     */
    private final String home;

    public Jvm() {
        Properties props = System.getProperties();
        this.version = props.getProperty("java.version");
        this.home = props.getProperty("java.home");
    }

    public String getTotal() {
        return DataSizeUtil.format(total);
    }

    public String getMax() {
        return DataSizeUtil.format(max);
    }

    public String getFree() {
        return DataSizeUtil.format(free);
    }

    public String getUsed() {
        return DataSizeUtil.format(total - free);
    }

    public double getUsage() {
        return ArithUtils.mul(ArithUtils.div(total - free, total, 4), 100);
    }

    /**
     * 获取JDK名称
     */
    public String getName() {
        return SystemUtil.getRuntimeMXBean().getVmName();
    }

    /**
     * JDK启动时间
     */
    public String getStartTime() {
        return getJvmStartTime().format(DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN));
    }

    /**
     * JDK运行时间
     */
    public String getRunTime() {
        long between = LocalDateTimeUtil.between(getJvmStartTime(), LocalDateTime.now(), ChronoUnit.MILLIS);
        return DateUtil.formatBetween(between, BetweenFormatter.Level.SECOND);
    }

    /**
     * 运行参数
     */
    public String getInputArgs() {
        return ManagementFactory.getRuntimeMXBean().getInputArguments().toString();
    }

    /**
     * JDK启动时间
     */
    private LocalDateTime getJvmStartTime() {
        return LocalDateTime.ofInstant(Instant.ofEpochMilli(SystemUtil.getRuntimeMXBean().getStartTime()), ZoneId.systemDefault());
    }
}
